package bee2d.spritesheet;

import bee2d.spritesheet.Behavior;
import bee2d.spritesheet.Frame;
import nme.display.Bitmap;
#if !flash
import nme.display.Tilesheet;
#end
import nme.display.BitmapData;
import nme.geom.Point;
import nme.geom.Rectangle;
import nme.geom.Rectangle;
import nme.Vector;

/**
 * ...
 * @author Joshua Granick
 */

class Spritesheet {
	
	public var behaviors:Hash <Behavior>;
	public var totalFrames:Int;
	
	private var frames:Vector <Frame>;
	private var sourceImage:BitmapData;
		
	#if (cpp||neko)
	private var tileSheet:Tilesheet;
	#end
	private var tileInfos:Vector<Rectangle>;
	private var tileBitmapDatas:Vector<BitmapData>; //每一块的位图数据
	public var name:String;
	public function new (image:BitmapData = null, frames:Vector <Frame> = null, behaviors:Hash <Behavior> = null) {
		this.sourceImage = image;
		
		if (frames == null) {
			
			this.frames = new Vector <Frame> ();
			totalFrames = 0;
			
		} else {
			
			this.frames = frames;
			totalFrames = frames.length;
			
		}
		
		if (behaviors == null) {
			
			this.behaviors = new Hash <Behavior> ();
			
		} else {
			
			this.behaviors = behaviors;
			
		}
		
		tileInfos = new Vector<Rectangle>();
		
		#if (cpp||neko)
		tileSheet = new Tilesheet(sourceImage);
		#end
		var tileIndex:Hash<Int> = new Hash<Int>();
		var tileText:String;
		var tileid:Int = 0;
		
		for (frame in frames) {
			tileText = frame.x + "," + frame.y + "," + frame.width + "," + frame.height;
			if (!tileIndex.exists(tileText)) {
				#if (cpp||neko)
				tileSheet.addTileRect(new Rectangle(frame.x, frame.y, frame.width, frame.height));
				#end
				tileInfos.push(new Rectangle(frame.x, frame.y, frame.width, frame.height));
				tileIndex.set(tileText, tileid);
				frame.tileid = tileid;
				tileid += 1;
			}else {
				frame.tileid = tileIndex.get(tileText);
			}
		}
		#if flash
		tileBitmapDatas = new Vector<BitmapData>(tileInfos.length);
		#else
		tileBitmapDatas = new Vector<BitmapData>();
		#end
	}
	
	public inline function getFrameBitmapData(frame:Frame):BitmapData {
		var _bitmapData:BitmapData = tileBitmapDatas[frame.tileid];
		if (_bitmapData==null) {
			_bitmapData = generateBitmap(frame.tileid);
			tileBitmapDatas[frame.tileid] = _bitmapData;
		}
		return _bitmapData;
	}
	public function getFrame (index:Int):Frame {
		return frames[index];
	}
	
	private function generateBitmap (tileid:Int):BitmapData {
		var rect:Rectangle = tileInfos[tileid];
		var bitmapData = new BitmapData (Std.int(rect.width),Std.int(rect.height), true);
		bitmapData.copyPixels (sourceImage, rect, new Point ());
		return bitmapData;
	}
	private static inline function getBitmapData(spritesheet:Spritesheet,frame:Frame):BitmapData {
		var _bitmapData:BitmapData =untyped spritesheet.tileBitmapDatas[frame.tileid];
		if (_bitmapData==null) {
			untyped _bitmapData = spritesheet.generateBitmap(frame.tileid);
			untyped spritesheet.tileBitmapDatas[frame.tileid] = _bitmapData;
		}
		return _bitmapData;
	}
}